#include <hal_configer.h>
#include "hal_errorcode.h"
#include "hal_eeprom.h"
#include "hal_current.h"
#include "hal_temp.h"
#include "hal_tlv.h"
#include "cfg_drive.h"
#include "sys_log.h"
#include "common.h"
#include <string.h>

int OVPFlag = 0;

uint32_t TA_CHANNEL_LD_ON_PIN_STATE = GPIO_PIN_RESET;

void LaserInit()
{
    SLOG_I("laser LaserInit start \t\r\n");

    // 电流源1脉冲激活
		
			LASER_GPIO_WRITE_PIN(CH1_REG_CPTART, GPIO_PIN_RESET);
			systick_delay_ms(10);
			LASER_GPIO_WRITE_PIN(CH1_REG_CPTART, GPIO_PIN_SET);
			systick_delay_ms(10);
			LASER_GPIO_WRITE_PIN(CH1_REG_CPTART, GPIO_PIN_RESET);
			systick_delay_ms(10);
		
    

    // 电流源2脉冲激活
    LASER_GPIO_WRITE_PIN(CH2_REG_CPTART, GPIO_PIN_RESET);
    systick_delay_ms(10);
    LASER_GPIO_WRITE_PIN(CH2_REG_CPTART, GPIO_PIN_SET);
    systick_delay_ms(10);
    LASER_GPIO_WRITE_PIN(CH2_REG_CPTART, GPIO_PIN_RESET);
    systick_delay_ms(10);
	
		hal_CurrentInit();
    //SLOG_I("laser hal_CurrentInit success \t\r\n");

    hal_TempInit();
    //SLOG_I("laser hal_TempInit success \t\r\n");
		

    // EEPROM全部参数获取,如果反馈正常则继续，不正常则不配置电流源和温控芯片
    /*if (hal_AllLaserEEPromInformInit() == NORMAL_STATE)
    {
        hal_CurrentInit();
        SLOG_I("laser hal_CurrentInit success \t\r\n");

        hal_TempInit();
        SLOG_I("laser hal_TempInit success \t\r\n");
    }
    else
    {
        SLOG_I("laser hal_AllLaserEEPromInformInit error \t\r\n");
    }*/
}

uint8_t hal_LaserReadValueNormal(LaserJudgeLimitTypeEn LaserJudgeLimitType, float data, int laser_num)
{
    float lower_limit = 0, upper_limit = 0;
    char type_r[50] = "no_error";
    static uint16_t cnt_r[2][6] = {0}; // 计数器用于跟踪每种错误类型的异常次数

    switch (LaserJudgeLimitType)
    {
    // 温度
    case JUDGE_LASER_LIMIT_TYPE_TEMP:
        lower_limit = TEMP_LOW_LIMIT;
        upper_limit = TEMP_HIGH_LIMIT;
        strcpy(type_r, "temp_error");
        break;
    // 通道一/二电流，异常值会修改为0因此不会触发
    case JUDGE_LASER_LIMIT_TYPE_CURRENT_SEED:
#if MODEL_CHOICE == MODEL_LASER_TA
        lower_limit = CURRENT_LOW_LIMIT_TA_LASER_SEED;
        upper_limit = CURRENT_HIGH_LIMIT_TA_LASER_SEED;
        strcpy(type_r, "current_seed_ta_error");
#elif MODEL_CHOICE == MODEL_LASER_DFB
        lower_limit = CURRENT_LOW_LIMIT_DFB_LASER_SEED;
        upper_limit = CURRENT_HIGH_LIMIT_DFB_LASER_SEED;
        strcpy(type_r, "current_seed_dfb_error");
#endif
        break;
    // TA工作电流
    case JUDGE_LASER_LIMIT_TYPE_CURRENT_TA:
        lower_limit = CURRENT_LOW_LIMIT_TA_LASER_TA;
        upper_limit = CURRENT_HIGH_LIMIT_TA_LASER_TA;
        strcpy(type_r, "current_work_ta_error");
        break;
    // PD电流，一般工作电流先超阈值，这个值触发设置异常
    case JUDGE_LASER_LIMIT_TYPE_PD:
        lower_limit = CURRENT_LOW_LIMIT_TA_LASER_PD;
        upper_limit = CURRENT_HIGH_LIMIT_TA_LASER_PD;
        strcpy(type_r, "current_pd_ta_error");
        break;
    // 未知的种类
    default:
        return 0;
    }

    // 不在阈值范围内，值异常
    if (data < lower_limit || data > upper_limit)
    {
        hal_ErrorCodeWrite(ERRORCODE_TYPE_LASER, s_Read_Value_Abnormal_Flag, laser_num, ABNORMAL_STATE);

        // 增加异常计数器
        cnt_r[laser_num-1][LaserJudgeLimitType]++;
        if (cnt_r[laser_num-1][LaserJudgeLimitType] % LASER_PROTECT_LOG_TIMER == 1) 
        {
            SLOG_I("laser read error lasernum: %d, type_r: %s, data: %f \t\r\n", laser_num, type_r, data);
        }
        
        return 0;
    }

    return 1;
}

uint8_t hal_LaserWriteValueNormal(LaserJudgeLimitTypeEn LaserJudgeLimitType, float data, int laser_num)
{
    float lower_limit = 0, upper_limit = 0;
    char type_w[50] = "no_error";
    static uint16_t cnt_w[2][6] = {0}; // 计数器用于跟踪每种错误类型的异常次数

    switch (LaserJudgeLimitType)
    {
    // 温度
    case JUDGE_LASER_LIMIT_TYPE_TEMP:
        lower_limit = TEMP_LOW_LIMIT;
        upper_limit = TEMP_HIGH_LIMIT;
        strcpy(type_w, "temp_error");
        break;
    // 通道一/二电流
    case JUDGE_LASER_LIMIT_TYPE_CURRENT_SEED:
#if MODEL_CHOICE == MODEL_LASER_TA
        lower_limit = CURRENT_LOW_LIMIT_TA_LASER_SEED;
        upper_limit = CURRENT_HIGH_LIMIT_TA_LASER_SEED;
        strcpy(type_w, "current_seed_ta_error");
#elif MODEL_CHOICE == MODEL_LASER_DFB
        lower_limit = CURRENT_LOW_LIMIT_DFB_LASER_SEED;
        upper_limit = CURRENT_HIGH_LIMIT_DFB_LASER_SEED;
        strcpy(type_w, "current_seed_dfb_error");
#endif
        break;
    // TA工作电流
    case JUDGE_LASER_LIMIT_TYPE_CURRENT_TA:
#if MODEL_CHOICE == MODEL_LASER_TA
        lower_limit = CURRENT_LOW_LIMIT_TA_LASER_TA;
        upper_limit = CURRENT_HIGH_LIMIT_TA_LASER_TA;
        strcpy(type_w, "current_work_ta_error");
#elif MODEL_CHOICE == MODEL_LASER_DFB
        lower_limit = CURRENT_LOW_LIMIT_DFB_LASER_SEED;
        upper_limit = CURRENT_HIGH_LIMIT_DFB_LASER_SEED;
        strcpy(type_w, "current_seed_dfb_error");
#endif
        break;
    // PD电流
    case JUDGE_LASER_LIMIT_TYPE_PD:
        lower_limit = CURRENT_LOW_LIMIT_TA_LASER_PD;
        upper_limit = CURRENT_HIGH_LIMIT_TA_LASER_PD;
        strcpy(type_w, "current_pd_ta_error");
        break;
    // 未知的种类
    default:
        return 0;
    }

    // 不在阈值范围内，值异常
    if (data < lower_limit || data > upper_limit)
    {
        hal_ErrorCodeWrite(ERRORCODE_TYPE_LASER, s_Write_Value_Abnormal_Flag, laser_num, ABNORMAL_STATE);

        // 增加异常计数器，设置5次触发一次即可
        cnt_w[laser_num-1][LaserJudgeLimitType]++;
        if (cnt_w[laser_num-1][LaserJudgeLimitType] % LASER_PROTECT_WRITE_LOG_TIMER == 1) 
        {
            SLOG_I("laser write error lasernum: %d, type_w: %s, data: %f \t\r\n", laser_num, type_w, data);
        }
        
        return 0;
    }

    return 1;
}

void hal_LaserGpioPinStateRead(uint8_t lasernum)
{
    char type_gpio[2][50] = {{""}, {""}};
    char fine_out[100] = "";
    static uint16_t cnt_gpio[2]= {0}; // 计数器用于跟踪每种错误类型的异常次数

    // 通道相关引脚电平状态
    // OCP
    if (LASER_GPIO_READ_PIN((lasernum == LASER_NUMBER_CHAN_1) ? CH1_REG_OCP : CH2_REG_OCP) == GPIO_PIN_SET)
    {
        hal_ErrorCodeWrite(ERRORCODE_TYPE_LASER, l_Ocp_Flag, lasernum, ABNORMAL_STATE);
        SLOG_I("laser channel %d OCP \t\r\n", lasernum);
    }

    // OVP
    if (LASER_GPIO_READ_PIN((lasernum == LASER_NUMBER_CHAN_1) ? CH1_REG_OVP : CH2_REG_OVP) == GPIO_PIN_SET)
    {
			OVPFlag = 1;
        hal_ErrorCodeWrite(ERRORCODE_TYPE_LASER, l_Ovp_Flag, lasernum, ABNORMAL_STATE);
        SLOG_I("laser channel %d OVP \t\r\n", lasernum);
    }

    // OT
    if (LASER_GPIO_READ_PIN((lasernum == LASER_NUMBER_CHAN_1) ? CH1_REG_OT : CH2_REG_OT) == GPIO_PIN_RESET)
    {
        hal_ErrorCodeWrite(ERRORCODE_TYPE_LASER, l_Ot_Flag, lasernum, ABNORMAL_STATE);
        SLOG_I("laser channel %d OT \t\r\n", lasernum);
    }

    // UT
    if (LASER_GPIO_READ_PIN((lasernum == LASER_NUMBER_CHAN_1) ? CH1_REG_UT : CH2_REG_UT) == GPIO_PIN_RESET)
    {
        hal_ErrorCodeWrite(ERRORCODE_TYPE_LASER, l_Ut_Flag, lasernum, ABNORMAL_STATE);
        SLOG_I("laser channel %d UT \t\r\n", lasernum);
    }

#if MODEL_CHOICE == MODEL_LASER_TA
    if (lasernum == LASER_NUMBER_CHAN_1)
    {
        if (LASER_GPIO_READ_PIN(CH1_REG_LD_ON) == GPIO_PIN_SET)
        {
            hal_ErrorCodeWrite(ERRORCODE_TYPE_LASER, l_Current_Source_Open, 1, 1);
            strcpy(type_gpio[0], "TA LD ON open");
        }
        else
        {
            hal_ErrorCodeWrite(ERRORCODE_TYPE_LASER, l_Current_Source_Open, 1, 0);
            strcpy(type_gpio[0], "TA LD ON close");
        }
    }

    if (lasernum == LASER_NUMBER_CHAN_2)
    {
        if ((LASER_GPIO_READ_PIN(CH2_REG_OCP) == GPIO_PIN_SET) || (LASER_GPIO_READ_PIN(CH2_REG_OVP) == GPIO_PIN_SET) || (TA_CHANNEL_LD_ON_PIN_STATE == GPIO_PIN_RESET))
        {
            hal_ErrorCodeWrite(ERRORCODE_TYPE_LASER, l_Current_Source_Open, 2, 0);
            strcpy(type_gpio[0], "TA LD ON open");
        }
        else if (TA_CHANNEL_LD_ON_PIN_STATE == GPIO_PIN_SET)
        {
            hal_ErrorCodeWrite(ERRORCODE_TYPE_LASER, l_Current_Source_Open, 2, 1);
            strcpy(type_gpio[0], "TA LD ON close");
        }
    }
    
#elif MODEL_CHOICE == MODEL_LASER_DFB
    // LD_ON
    if (LASER_GPIO_READ_PIN((lasernum == LASER_NUMBER_CHAN_1) ? CH1_REG_LD_ON : CH2_REG_LD_ON) == GPIO_PIN_SET)
    {
        hal_ErrorCodeWrite(ERRORCODE_TYPE_LASER, l_Current_Source_Open, lasernum, 1);
        strcpy(type_gpio[0], "DFB LD ON open");
    }
    else
    {
        hal_ErrorCodeWrite(ERRORCODE_TYPE_LASER, l_Current_Source_Open, lasernum, 0);
        strcpy(type_gpio[0], "DFB LD ON close");
    }
#endif

    // SHDN_ON
    if (LASER_GPIO_READ_PIN((lasernum == LASER_NUMBER_CHAN_1) ? CH1_REG_SHDN : CH2_REG_SHDN) == GPIO_PIN_SET)
    {
        hal_ErrorCodeWrite(ERRORCODE_TYPE_LASER, l_Temperature_Chip_Open, lasernum, 1);
        strcpy(type_gpio[1], "SHDN ON open");
    }
    else
    {
        hal_ErrorCodeWrite(ERRORCODE_TYPE_LASER, l_Temperature_Chip_Open, lasernum, 0);
        strcpy(type_gpio[1], "SHDN ON close");
    }

    cnt_gpio[lasernum-1]++;
	if (cnt_gpio[lasernum-1] % POLL_CMD_LOG_TIME == 1) 
	{
		fine_out[0] = '\0'; // 清空fine_out
		int len = 0;
		for(int i=0; i<2; i++)
		{
			// 检查添加新的字符串是否会超出fine_out的大小
            strncat(fine_out + len, type_gpio[i], sizeof(fine_out) - len - 1);
            len += strlen(type_gpio[i]);
            if (i < 2) 
            { 
                // 添加分隔符，除了最后一个字符串
                strncat(fine_out + len, ", ", sizeof(fine_out) - len - 1);
                len += 2;
            }
		}
		SLOG_I("laser channel %d, %s \t\r\n", lasernum, fine_out);
	}
}
